package calc

import (
	"JiXiaoCalc/config"
	"JiXiaoCalc/excel"
	"JiXiaoCalc/log"
	"JiXiaoCalc/model"
	"fmt"

	"github.com/xuri/excelize/v2"
	"regexp"
	"strconv"
	"strings"
)

var indices *model.ExcelInfo

func parseSystemInfo(info *model.SystemInfo, row []string) error {
	log.Logger().Info("开始解析系统情况信息")
	if len(row) <= indices.SystemInfoIndex {
		errMsg := "行数据长度不足，无法解析系统情况"
		log.Logger().Error(errMsg)
		return fmt.Errorf(errMsg)
	}
	systemInfo := row[indices.SystemInfoIndex]
	re := regexp.MustCompile(`\{([^}]+)}`)
	matches := re.FindAllStringSubmatch(systemInfo, -1)
	log.Logger().Info("完成系统信息片段匹配")

	for _, match := range matches {
		parts := strings.Split(match[1], "/")
		if len(parts) == 4 {
			systemType := parts[0]
			businessType := parts[1]
			businessTypeQty, err := strconv.ParseFloat(parts[2], 64)
			if err != nil {
				log.Logger().Errorf("业务类型数量解析错误（内容：%s）：%v", parts[2], err)
				return fmt.Errorf("业务类型数量解析错误：%s", parts[2])
			}
			subsystemQty, err := strconv.ParseFloat(parts[3], 64)
			if err != nil {
				log.Logger().Errorf("子系统数量解析错误（内容：%s)：%v", parts[3], err)
				return fmt.Errorf("子系统数量解析错误：%s", parts[3])
			}

			info.SystemTypes = append(info.SystemTypes, systemType)
			info.BusinessTypes = append(info.BusinessTypes, businessType)
			info.SystemTypeQuantities = append(info.SystemTypeQuantities, businessTypeQty)
			info.SubsystemQuantities = append(info.SubsystemQuantities, subsystemQty)
			// （业务类型/天数），“技术支撑”
		} else if len(parts) == 2 && parts[0] == "技术支撑" {
			businessType := parts[0]
			days, err := strconv.ParseFloat(parts[1], 64)
			if err != nil {
				log.Logger().Errorf("技术支撑天数解析错误（内容：%s)：%v", parts[1], err)
				return fmt.Errorf("技术支撑天数解析错误：%s", parts[1])
			}
			info.BusinessTypes = append(info.BusinessTypes, businessType)
			info.Days = days
			info.IsTechSupport = true // 标记为技术支撑场景

		} else {
			log.Logger().Errorf("系统情况格式错误：%s", match[0])
			return fmt.Errorf("系统情况格式错误：%s", match[0])
		}
	}
	return nil
}

func Calc(f *excelize.File, rows [][]string) {
	indices = excel.GetExcelInfo()
	var err error
	for index, row := range rows {
		index++
		// 跳过列数不足的无效行
		if len(row) <= indices.PerformanceRatioIndex {
			continue
		}
		systemInfo := &model.SystemInfo{}
		rowData := &model.RowData{
			SystemInfo: systemInfo,
		}
		if err = parseSystemInfo(systemInfo, row); err != nil {
			log.Logger().Errorf("第%d行解析失败：%v\n", index+1, err)
			continue
		}

		// 绩效比例解析
		perfRatioStr := strings.TrimSpace(row[indices.PerformanceRatioIndex])
		rowData.PerformanceRatio, err = strconv.ParseFloat(perfRatioStr, 64)
		if err != nil {
			log.Logger().Errorf("第%d行绩效比例解析错误：%v\n", index+1, err)
			continue
		}

		//计算系统总数和子系统总数
		calculateTotal(rowData)
		//计算基点数量、折扣比例
		calculateBasePoints(rowData)
		// 计算项目基数、申请金额、最终金额
		calculatePerformance(rowData)
		// 将计算结果写入新列
		excel.WriteNewColumnData(f, rowData, index+1)

		//分配最终金额到人名列
		excel.AllocateAmountToPersons(f, index, rowData.FinalAmount, row)
	}
}

// 用来计算系统总数和子系统总数
func calculateTotal(data *model.RowData) {
	log.Logger().Info("开始计算系统总数和子系统总数")
	var systemTotal, subsystemTotal float64 = 0, 0
	if !data.SystemInfo.IsTechSupport {
		for _, v := range data.SystemInfo.SystemTypeQuantities {
			systemTotal += v
		}
		for _, v := range data.SystemInfo.SubsystemQuantities {
			subsystemTotal += v
		}
	}
	data.SystemTotal = systemTotal
	data.SubsystemTotal = subsystemTotal
	log.Logger().Info("系统总数和子系统总数计算完毕")
	return
}
func calculatePerformance(data *model.RowData) {
	log.Logger().Info("开始计算项目基数、申请金额、最终金额")
	//  CalculatePerformance 中技术支撑场景的处理
	if data.SystemInfo.IsTechSupport {
		data.ProjectBase = 100 * data.SystemInfo.Days
		data.ApplicationAmount = data.ProjectBase
		data.FinalAmount = data.ApplicationAmount * data.PerformanceRatio
		return
	}
	//计算项目基数=业务类型1绩效*类型1数量*系统类型1比例+业务类型2绩效*类型2数量*系统类型2比例+...
	//子系统绩效=业务类型绩效*0.2*子系统数量
	var subsystemPerformance, performanceValue float64
	for i, value := range data.SystemInfo.SystemTypes {
		performanceValue += config.BusinessPerformanceMap[data.SystemInfo.BusinessTypes[i]] * data.SystemInfo.SystemTypeQuantities[i] * config.SystemTypeMap[value]
		subsystemPerformance += config.BusinessPerformanceMap[data.SystemInfo.BusinessTypes[i]] * data.SystemInfo.SubsystemQuantities[i] * 0.2
	}
	data.ProjectBase = performanceValue
	//计算申请金额=项目基数 * 折扣比例（即系统总数比例）+子系统绩效
	data.ApplicationAmount = data.ProjectBase*data.ZheKouBiLi + subsystemPerformance
	//计算最终金额=申请金额 * 绩效比例
	data.FinalAmount = data.ApplicationAmount * data.PerformanceRatio
	log.Logger().Info("项目基数、申请金额、最终金额计算完毕")
	return
}

// 计算基点数量、折扣比例
func calculateBasePoints(data *model.RowData) {
	log.Logger().Info("开始计算基点数量和折扣比例")
	// 技术支撑场景：基点数量=0.2×总天数
	if data.SystemInfo.IsTechSupport {
		// 直接取第一个元素（总天数）
		data.BasePoints = 0.2 * data.SystemInfo.Days
		data.ZheKouBiLi = 1
		return
	}
	// 非技术支撑：计算businessValue总和
	businessValueSum := 0.0
	for i, value := range data.SystemInfo.BusinessTypes {
		bv := config.BusinessLevelMap[value] * data.SystemInfo.SystemTypeQuantities[i] * config.SystemTypeMap[data.SystemInfo.SystemTypes[i]]
		businessValueSum += bv
	}
	// 系统数量对应比例默认0.6
	if val, ok := config.SystemQuantityMap[data.SystemTotal]; ok {
		data.ZheKouBiLi = val
	} else {
		data.ZheKouBiLi = 0.6
	}

	// 最终基点数量
	data.BasePoints = data.SubsystemTotal*0.2 + data.ZheKouBiLi*businessValueSum
	log.Logger().Info("基点数量、折扣比例计算完毕")
	return
}
